<template>
  <q-page class="row" v-if="!error">
    <!-- 搜索栏 -->
    <q-page-sticky position="top" expand class="bg-grey-1 text-white" style="z-index: 99;" v-if="!revealed">
      <headerBar dense v-model="filter.query" :placeholder="placeholder" />
    </q-page-sticky>

    <!-- 头栏 -->
    <q-header reveal bordered class="bg-white text-dark q-py-sm" @reveal="revealHeader">
      <headerBar v-model="filter.query" :placeholder="placeholder" />
      <q-toolbar>
        <q-avatar size="68px" rounded>
          <img :src="shop.logo_img">
        </q-avatar>
        <div class="q-ml-md fit">
          <div class="text-bold row" style="font-size: 22px;">{{ shop.shop_name }}<q-space /><div style="font-size: 10px;" class="text-grey-6">人气:{{ shop.pv }}</div></div>
          <div>联系人：{{ shop.linkman }}</div>
          <div class="row">
            <div>电话：{{ shop.tel }}</div>
            <div class="q-ml-sm">短号：{{ shop.short_tel }}</div>
          </div>
        </div>
      </q-toolbar>
      <div class="q-px-md q-py-xs">地址：{{ shop.address }}</div>
    </q-header>

    <!-- 分类栏 -->
    <q-drawer v-model="left" side="left" bordered behavior="desktop" :width="100">
      <q-scroll-area class="fit">
        <q-tabs v-model="activeSubId.level_0" vertical class="bg-grey-2 text-grey-8 vertical-tabs" active-class="bg-white text-dark text-bold" indicator-color="orange" switch-indicator>
          <q-tab :name="item.uid" :label="item.catalog_name" v-for="item of catalog" :key="item.uid" />
        </q-tabs>
      </q-scroll-area>
    </q-drawer>

    <!-- 商品栏 -->
    <div class="q-pa-sm fit">
      <!-- 子分类栏 -->
      <div>
        <q-tabs
          v-for="(row, idx) in catalogStructure"
          :key="idx"
          v-model="activeSubId['level_' + (idx + 1)]"
          inline-label
          mobile-arrows
          dense
          align="left"
          :breakpoint="0"
          class="bg-grey-2 text-primary q-mb-xs"
          active-color="white"
          active-bg-color="primary"
        >
          <q-tab v-for="item of row" :key="item.label" :name="item.uid" :label="item.catalog_name" @click="getSubCatalog(item.uid, item.levels)" />
        </q-tabs>
      </div>

      <q-infinite-scroll @load="onLoad" :offset="250" ref="goodsScroll">
        <div v-for="(item, idx) in data" :key="idx" class="q-my-md">
          <q-card flat>
            <q-card-section horizontal>
              <goodsItem :item="item" @add="addCart(item)" @remove="removeCart(item)" @detail="toDetail(item)" />
            </q-card-section>
          </q-card>
        </div>
        <template v-slot:loading>
          <div class="row justify-center q-my-md">
            <q-spinner-dots color="primary" size="40px" />
          </div>
        </template>
      </q-infinite-scroll>
    </div>

    <!-- 购物车详情 -->
    <cartDialog ref="cartDialog" @update="updateCarts" />

    <!-- 底栏 -->
    <q-footer bordered class="bg-white text-dark" >
      <q-toolbar>
        <q-avatar size="58px" rounded @click="showCart">
          <img src="/images/cart.svg" />
        </q-avatar>
        <div class="q-pl-sm" @click="showCart">
          <div class="text-red text-bold" style="font-size: 16px; line-height: normal;">¥<a style="font-size: 30px;">{{ totalMoney[0] }}</a>{{ totalMoney[1] }}</div>
          <div class="text-grey-8" style="line-height: normal;">已选购{{ totalAmount }}件商品</div>
        </div>
        <q-space />
        <q-btn color="orange-4" size="16px" rounded unelevated text-color="black" label="去下单" @click="placeOrder" :disable="!carts || carts.length === 0" />
      </q-toolbar>
    </q-footer>
  </q-page>

  <div class="text-h4 text-center full-width" style="position: absolute; top: calc(50vh - 20px);" v-if="error">
    {{ error }}
  </div>
</template>

<script>
import { defineComponent } from 'vue';
import headerBar from './components/headerBar.vue';
import goodsItem from './components/goodsItem.vue';
import cartDialog from './components/cartDialog.vue';
import { useShopStore } from 'stores/shop';
import { mapState, mapActions } from 'pinia';

export default defineComponent({
  name: 'shopList',
  components: {
    headerBar,
    goodsItem,
    cartDialog
  },
  data () {
    return {
      shop: { // 店铺信息
        id: null,
        shop_name: '',
        linkman: '',
        tel: '',
        short_tel: '',
        address: '',
        logo_img: '',
        intro: '',
        pv: 0
      },
      catalog: [], // 商品分类
      error: null, // 错误信息
      carts: [], // 购物车 [{uid, material_name, material_model, material_unit, sale_price, images, cart_amount}...]

      left: true, // 左栏是否显示

      revealed: true, // 头栏是否显示

      data: [],
      pagination: {
        sortBy: '',
        descending: true,
        page: 1,
        rowsPerPage: 20,
        rowsNumber: 0
      },
      filter: { // 过滤条件
        catalog_id: '',
        level: 1,
        query: ''
      },
      lastFilter: {
        catalog_id: '',
        query: ''
      },

      subCatalogData: [], // 所有子分类
      catalogStructure: [], // 结构化分类
      activeSubId: { level_0: '' }, // 当前激活的子分类id
      pageKey: 'list'
    }
  },
  created () {
    this.shop.id = this.$route.params.id;
    this.$q.localStorage.set('myShop', this.shop.id);
  },
  mounted () {
    if (this.$q.localStorage.has(this.cartId)) {
      this.carts = this.$q.localStorage.getItem(this.cartId).carts;
    }

    // 取店铺信息
    this.$axios.get('/c/shop/info', { params: { id: this.shop.id } }).then(({ data }) => {
      if (data.result === 'fail') {
        this.error = data.message;
      } else {
        this.shop = { ...data.shop, id: this.shop.id };
      }
    });

    // 取商品分类
    this.$axios.get('/c/shop/catalog', { params: { id: this.shop.id } }).then(({ data }) => {
      this.catalog = data.catalog;
      // this.activeSubId.level_0 = data.catalog[0].uid;

      this.restorePage()
    });
  },
  beforeUnmount () {
    this.saveScrollTop(this.pageKey);
  },
  methods: {
    ...mapActions(useShopStore, ['getPageParams', 'savePageParams', 'saveScrollTop', 'restoreScrollTop']),
    addCart (item) { // 添加到购物车
      const cart = this.carts.find(cart => cart.uid === item.uid);
      if (cart) {
        cart.cart_amount += 1;
      } else {
        item.cart_amount = 1;
        this.carts.push(item);
      }
      this.$q.localStorage.set(this.cartId, { shopName: this.shop.shop_name, carts: this.carts });
    },
    removeCart (item) { // 移除购物车
      const idx = this.carts.findIndex(cart => cart.uid === item.uid);
      if (idx >= 0) {
        const cart = this.carts[idx];
        cart.cart_amount -= 1;
        if (cart.cart_amount <= 0) {
          this.carts.splice(idx, 1);
        }
      }
      if (this.carts.length > 0) {
        this.$q.localStorage.set(this.cartId, { shopName: this.shop.shop_name, carts: this.carts });
      } else {
        this.$q.localStorage.remove(this.cartId);
      }
    },
    linkCart () { // 数据重取后，新数据与购物车重新关联
      for (const row of this.data) {
        const idx = this.carts.findIndex(cart => cart.uid === row.uid);
        if (idx >= 0 && this.carts[idx] !== row) {
          row.cart_amount = this.carts[idx].cart_amount;
          this.carts[idx] = row;
        }
      }
    },
    updateCarts (carts) {
      this.carts = carts;
      this.linkCart();
    },
    revealHeader (val) {
      this.revealed = val;
    },
    fetchData (cb) {
      const { page, rowsPerPage, sortBy, descending } = this.pagination;
      const filter = this.filter;

      const startRow = (page - 1) * rowsPerPage;
      const count = rowsPerPage;
      this.$axios.post(`/c/shop/list?shop=${this.shop.id}`, { startRow, count, filter, sortBy, descending }).then(({ data }) => {
        this.pagination.rowsNumber = data.rowsNumber;
        this.pagination.page = page;

        if (this.lastFilter.catalog_id !== filter.catalog_id || this.lastFilter.query !== filter.query) {
          this.data = data.data;
          this.$refs.goodsScroll.reset();
        } else {
          const rows = data.data.filter(v => !this.data.find(d => d.uid == v.uid)); // 重复不添加
          this.data.push(...rows);
        }
        this.lastFilter.catalog_id = filter.catalog_id;
        this.lastFilter.query = filter.query;

        this.linkCart();

        if (cb && typeof cb === 'function') {
          cb();
        }
      });
    },
    onLoad (index, done) {
      const totalPage = Math.ceil(this.pagination.rowsNumber / this.pagination.rowsPerPage);

      if (index <= totalPage) {
        this.pagination.page = index;
        this.fetchData();
      }

      done();
    },
    splitMoney (money) {
      const arr = String(Number(Number(money).toFixed(2))).split('.');
      if (arr.length === 1) {
        return [arr[0], ''];
      } else {
        return [arr[0], '.' + arr[1]];
      }
    },
    showCart () {
      if (this.carts.length > 0) {
        this.$refs.cartDialog.show();
      }
    },
    placeOrder () { // 去下单
      if (this.carts.length === 0) {
        this.$q.notify({
          message: '请添加采购后再去下单',
          color: 'info',
          icon: 'error',
          position: 'center',
          timeout: 4000
        });
        return;
      }

      const token = this.$q.localStorage.getItem('consumerToken');
      const consumer = this.$q.localStorage.getItem('consumer');

      if (token && consumer) {
        this.$router.push('/shop/order');
      } else {
        this.$router.replace({ path: '/shop/login' });
      }
    },
    toDetail (item) {
      const path = { path: `/shop/detail/${item.uid}` };
      this.$router.push(path);
    },
    getSubCatalog (uid, level) {
      this.catalogStructure.splice(level);

      const subCata = this.subCatalogData.filter(v => v.parent_uid == uid);
      if (subCata.length > 0) this.catalogStructure.push(subCata);

      this.activeSubId['level_' + level] = uid;
      for (const key in this.activeSubId) {
        const keyLevel = Number(key.replace('level_', ''));
        if (keyLevel > level) {
          this.activeSubId[key] = '';
        }
      }

      this.pagination.page = 1;
      this.filter.catalog_id = uid;
      this.filter.level = level + 1;
      this.fetchData();

      this.savePageParams(this.pageKey, { activeSubId: this.activeSubId, filter: this.filter });
    },
    restorePage () { // 恢复分页参数
      const pageParas = this.getPageParams(this.pageKey);
      if (pageParas) {
        this.filter = pageParas.filter;

        this.activeSubId = pageParas.activeSubId;
      } else {
        this.activeSubId.level_0 = this.catalog[0].uid;
      }
    }
  },
  computed: {
    totalMoney () {
      const money = this.carts.reduce((a, b) => a + Number(b.sale_price) * Number(b.cart_amount), 0);
      return this.splitMoney(money);
    },
    cartId () {
      return `${this.shop.id || ''}_carts`;
    },
    placeholder () {
      const item = this.catalog.find(v => v.uid === this.filter.catalog_id);
      return `搜索 ${item && item.catalog_name || ''}里${this.pagination.rowsNumber}件 商品...`;
    },
    totalAmount () {
      return this.carts.reduce((a, b) => a + b.cart_amount, 0);
    }
  },
  watch: {
    'activeSubId.level_0' (val) {
      this.pagination.page = 1;
      this.filter.catalog_id = val;
      this.filter.level = 1;
      this.fetchData();

      this.$axios.get('/c/shop/subCatalog', { params: { id: val } }).then(({ data }) => {
        this.subCatalogData = data;
        this.getSubCatalog(val, 0);
      });

      this.savePageParams(this.pageKey, { activeSubId: this.activeSubId, filter: this.filter });
    },
    'filter.query' () {
      this.pagination.page = 1;
      this.fetchData();

      this.savePageParams(this.pageKey, { activeSubId: this.activeSubId, filter: this.filter });
    }
  }
});
</script>

<style lang="scss">
.vertical-tabs .q-tab__indicator {
  width: 5px!important;
}
</style>
